package project.layer.ant;

import framework.events.EventBroker;
import project.events.antEvents.FollowingExplorationAntCreatedEvent;
import project.events.antEvents.FollowingExplorationAntDiedEvent;
import project.events.antEvents.FollowingExplorationAntMovedEvent;
import project.layer.agents.PickUpPointAgent;
import project.layer.agents.ReportReceiver;
import project.layer.agents.TruckAgent;
import project.layer.agents.TruckAgentStatePickingUpPackage;
import project.layer.devices.AStarRouter;
import project.layer.physical.Crossroad;
import project.layer.physical.Path;
import project.layer.physical.Road;

public class FollowingExplorationAnt extends ExplorationAnt {

	private int followingID;

//	public FollowingExplorationAnt(TruckAgent sendingAgent, Crossroad location,
//			int maxHops, int nbOfPnDSequencesLeft, int followingID) {
//		super(sendingAgent, location, maxHops, nbOfPnDSequencesLeft);
//
//		this.followingID = followingID;
//		EventBroker.getEventBroker().notifyAll(
//				new FollowingExplorationAntCreatedEvent(this));
//	}

	FollowingExplorationAnt(TruckAgent sendingAgent, ReportReceiver receiver, ReportReceiver earlierReceiver, Crossroad location,
			int maxHops, int currentHopCount, Path currentPath,
			int nbOfPnDSequencesLeft, Road lastRoad, long travelledDistance, Path previousPath, int followingID) {
		super(sendingAgent, receiver, earlierReceiver, location, maxHops, currentHopCount, currentPath,
				nbOfPnDSequencesLeft, lastRoad, travelledDistance, previousPath);
		this.followingID = followingID;
		
		EventBroker.getEventBroker().notifyAll(
				new FollowingExplorationAntCreatedEvent(this));
	}

	@Override
	public void processAntTick() {
		// int truckId = this.getAnt().getId();
		
		Crossroad location = getLocation();
		increaseHopCount();
		followedPath.addCrossroadToPath(location);
		if(getTravelledDistance() != followedPath.getTotalDistance()){
			System.out.println(hasPreviousPath());
			
		}

		if (getRemainingHops() > 0) {
			
			if (location.hasPickUpPoint()
					&& location.getPickUpPoint().hasPackage()
					&& location.getPickUpPoint().getCorrespondingAgent().getId() == getFollowingID()) {
				// this.foundPackage(crossroad);

				PickUpPointAgent agent = (PickUpPointAgent) location
						.getPickUpPoint().getCorrespondingAgent();
				followedPath.addToDestinations(agent.getId());
				Path pathToDestination = agent.getPathToPackage();
				followedPath.add(pathToDestination);
				//A STAR doesn't include first crossroad, so we add it to get accurate total distance
				pathToDestination.addCrossroadToFrontOfPath(getLocation());
				increaseTravelledDistance(pathToDestination.getTotalDistance());
				
				if(getNbOfPnDSequencesLeft() == 1){
					getReceiver().reportPath(getPath(), getEarlierReceiver());
					die();
				}
				else{
					die();
					agent.reportPathTo(getPath(), getDestinationsOfPreviousPnDSequences(),getReceiver(), getEarlierReceiver(), getSendingAgent(), getNbOfPnDSequencesLeft()-1, getTravelledDistance());
					
				}
				
			} else {
				
				Road road = location.getDataHolder()
						.getRoadWithMostFeasibilityPheromones(getDestinationsOfPreviousPnDSequences(), getFollowingID());
				if (road != null){
					followRoadSigns(road, location);
					
				}
					
				else
					die();
			}
		} else {
			die();
		}
	}

	private void followRoadSigns(Road road, Crossroad crossroad) {
		// dropTag();
		Crossroad nextCrossroad = road.getOtherConnector(crossroad);
		if(followedPath.contains(nextCrossroad)){
			die();
		}
		else{
			setLocation(nextCrossroad);
			increaseTravelledDistance(road.getLength());
			EventBroker.getEventBroker().notifyAll(
					new FollowingExplorationAntMovedEvent(this));
			setLastRoad(road);
		}
		
	}

	@Override
	protected void createDieEvent() {
		EventBroker.getEventBroker().notifyAll(
				new FollowingExplorationAntDiedEvent(this));

	}

	public int getFollowingID() {
		return followingID;
	}

}
